package games.mapacman.server;

import aa.core.ActorMessage;
import com.agentslab.constants.APIConstants;
import games.mapacman.common.Common;
import games.mapacman.common.Constants;

import java.util.Random;
import java.util.Vector;

import marauroa.common.Log4J;
import marauroa.common.game.IRPZone;
import marauroa.common.game.RPObject;
import marauroa.common.game.RPObject.ID;
import marauroa.server.game.Statistics;
import marauroa.server.game.rp.RPWorld;

public class MaPacmanRPWorld extends RPWorld {
	private static final marauroa.common.Logger logger = Log4J
			.getLogger(MaPacmanRPWorld.class);
	private Vector<RPObject> Players = new Vector<RPObject>();
	private Statistics stats;
	private Random randomGen = new Random();
	private int GhostMoveInt = 10;
	private static MaPacmanRPWorld instance = null;
        public boolean shouldStart=false;

	public static MaPacmanRPWorld get() {
		if (instance == null) {
			instance = new MaPacmanRPWorld();
			instance.initialize();
		}
		return instance;
	}


	private MaPacmanRPWorld() {
		super();
		Common.initRPClasses();
	}

	public void removePlayer(ID id) {
		RPObject player = this.get(id);
		((MaPacmanZone) getRPZone(id)).removePlayer(id);
		Players.remove(player);
		this.remove(id);
	}

        public void removeGhost(ID id) {
		RPObject ghost = this.get(id);
		((MaPacmanZone) getRPZone(id)).removeGhost(id);
		this.remove(id);
	}

	public boolean addPlayer(RPObject object) {
		// set GhostMoveInt, that Ghosts move 100turns after last player has
		// left
		GhostMoveInt = 100;

		for (IRPZone RPzone : this) {
			MaPacmanZone zone = (MaPacmanZone) RPzone;
			if (zone.getName().equals(object.get("zoneid"))) {
				this.add(object);
				zone.addPlayer(object);
				return Players.add(object);
			}
		}
		logger.debug("MaPacman::MaPacmanRPWorld::addPlayer Zone "
				+ object.get("zoneid") + "not found for Player "
				+ object.get("name"));
		return false;
	}

        public boolean addGhost(RPObject object) {

		for (IRPZone RPzone : this) {
			MaPacmanZone zone = (MaPacmanZone) RPzone;
			if (zone.getName().equals(object.get("zoneid"))) {
				this.add(object);
				zone.addGhost(object);
				object.put("type", Constants.TYPE_GHOST);
                                this.modify(object);
				return true;
			}
		}
		logger.debug("MaPacman::MaPacmanRPWorld::addGhost Zone "
				+ object.get("zoneid") + "not found for Ghost "
				+ object.get("name"));
		return false;
	}

         

	public Vector<RPObject> getPlayers() {
		return Players;
	}

	public void beginTurn() {		
                for (IRPZone RPzone : this) {
                    MaPacmanZone zone = (MaPacmanZone) RPzone;
//                    if(zone.getName().compareTo("start")!=0)
//                        zone.beginTurn();
//                    else if(shouldStart){
                        zone.beginTurn();
//                        System.err.println("beginning turn for zone: "+zone.getName());
//                    }
                }

        }

        public void clear() {
                for (IRPZone RPzone : this) {
                    MaPacmanZone zone = (MaPacmanZone) RPzone;
                    if(zone.getName().compareTo("start")!=0)
                        zone.clear();
                }

        }

	public boolean hasPlayer(RPObject newPlayer) {
		for (IRPZone RPzone : this) {
			for (RPObject player : ((MaPacmanZone) RPzone).getPlayers()) {
				if (player.get("name").equals(newPlayer.get("name"))) {
					return true;
				}
			}
		}
		return false;
	}

	public void setStats(Statistics stats) {
		this.stats = stats;

	}

	public Statistics getStats() {
		return stats;
	}

	public void changeZone(RPObject object, MaPacmanZone oldzone,
			String newZoneName) {
                //System.err.println("changeZone:MaPacmanRPWorld oldzone: "+oldzone.getName()+" newzone: "+newZoneName+" player obj: "+object);
		if (object.get("type").equals(Constants.TYPE_PLAYER)) {
			if(oldzone.getName().compareTo(newZoneName)==0){
                            changeZone(oldzone.getID(), object);                        
                        }
                        else{
                            for (IRPZone RPzone : this) {
                                    MaPacmanZone zone = (MaPacmanZone) RPzone;
                                    if (zone.getName().equals(newZoneName)) {
                                            changeZone(zone.getID(), object);
                                            oldzone.removePlayer(object.getID());
                                            zone.addPlayer(object);
                                            break;
                                    }
                            }
                        }
                        
		}
	}

	public Random getRandom() {
		return randomGen;
	}

	public boolean moveGhosts() {
		if (Players.size() > 0) {
			return true;
		} else if (GhostMoveInt > 0) {
			GhostMoveInt--;
			return true;
		}

		return false;
	}

}
